#include "app.h"


#define 	RUTA_IN		"./IN/Comando.7506"

//Inicializo la instancia en NULL
App* App::instancia = NULL;

App::App(){
	this->segundos_espera = 1; //por default	
}

App* App::get_instance(){
	if (App::instancia == NULL)
		App::instancia = new App();
	return App::instancia;
}

void App::pasar_in_out(std::ifstream &archivo_in){
	Logger * l = Logger::get_instance(); 
	l->comenzar_log();
	*l << archivo_in;
	archivo_in.clear();
	archivo_in.seekg (0, std::ios::beg);
}
		
int App::ejecutar (int argc, char* argv[]){
	try{
		//Parseamos los parametros que vienen por consola y los 
		//cargamos en el modelo
		ParserParametros parser_parametros ;
		parser_parametros.parsear(argv,argc);
		Modelo * modelo;
		modelo = new Modelo( parser_parametros.get_segundos() );
		Debug::get_instance()->set_activado(parser_parametros.get_monitoreo() );
		Buffer::get_instance(parser_parametros.get_tamanio_buffer());
		ManejadorArchivos::get_instance();
		Operacion * operacion = NULL;
		
		std::ifstream archivo_in;
		std::string aux;
		Fabrica_Operaciones fab;
		
		//mientras no este terminado (no llego op FINALIZAR)	
		while(!modelo->esta_terminado() ){
			//intento abrir, si no existe el archivo, espera,
			archivo_in.open(RUTA_IN);
			if (archivo_in.fail()) 
				sleep(get_segundos_espera());
			else{
				pasar_in_out(archivo_in);
				//getline(archivo_in,aux);
				while( (!archivo_in.eof()) && (!modelo->esta_terminado()) ){
					getline(archivo_in,aux);
					try{
						if(aux.compare("") != 0){
							//obtiene una una operacion a partir partir de
							//la linea leida y la ejecuta
							operacion = fab.crear_operacion(aux);
							if(operacion != NULL){ //por los comentarios
								operacion->ejecutar(modelo);
								delete operacion;
								operacion = NULL;
							}
						}
						
					}
					catch(std::runtime_error &e){
						std::string error = e.what();
						error.append(". RES = 0");
						(*Logger::get_instance()) << error;
						( Debug::get_instance() )->mostrar_mensaje(error);
						if (operacion != NULL) {
							delete operacion;
							operacion = NULL;
						}
					}
					//getline(archivo_in,aux);
					
				}
				(Logger::get_instance())->terminar_log();
				archivo_in.close();
				remove(RUTA_IN);
				
			}
		}
		delete modelo;
		ManejadorArchivos::destroy();
		Buffer::destroy();
		Logger::destroy();
		Debug::destroy();
	}
	catch(std::runtime_error &e){
		std::cerr << e.what() << "\n" ;
	}		
	return 0;	
}
		
void App::destroy(){
	delete App::instancia;
	App::instancia = NULL;	
}
